/* sockclnt.c*/
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /*for struct sockaddr_in*/
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h> 
#include <iostream>
#include <poll.h>
#include "socket.h" 

#define MAXBUF 16384
#define THREAD_NUM 1
#define SOCKET_NUM 1

using namespace std;

int client_port = 3330;
char *client_ip = "127.0.0.1";
//char *client_ip = "199.155.122.11";

void *thread_func(void *ptr);

int main(int argc, char *argv[])
{
	signal(SIGPIPE,SIG_IGN);

	pthread_t tid[THREAD_NUM];

	for(int i = 0;i < THREAD_NUM;i++)
	{
		pthread_create(&tid[i], NULL, thread_func, NULL);
	}
	
	for(int i = 0;i < THREAD_NUM;i++)
	{
		pthread_join(tid[i], NULL);
	}
	
	return 0;
}

void *thread_func(void *ptr){

	int sockfd[SOCKET_NUM];
	for(int i = 0; i < SOCKET_NUM; ++i){
		sockfd[i] = socket(AF_INET, SOCK_STREAM, 0);
		if (sockfd[i] == -1){
			perror("socket()");
			return NULL;
		}
		cout << "sockfd: " << sockfd[i] << endl;
	}

	struct sockaddr_in dest_addr;
	bzero(&dest_addr, sizeof(dest_addr));
	dest_addr.sin_family = AF_INET;
	dest_addr.sin_port = htons(client_port);
	dest_addr.sin_addr.s_addr = inet_addr(client_ip);

	struct  timeval begin,end;
	gettimeofday(&begin,0);
	
	int flag = 1;
	for(int i = 0; i < SOCKET_NUM; ++i){
		setsockopt(sockfd[i], SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
	}
	struct timeval connTimeout;
	connTimeout.tv_sec = 0;
	connTimeout.tv_usec = 100000;
	
	for(int i = 0; i < SOCKET_NUM; ++i){
		if (connect(sockfd[i], (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in)) != 0){
			cout << "fd :" << sockfd[i] << endl;
			perror("connect()");
			close(sockfd[i]);
			return NULL;
		}
	}
	
	cout << "connect sucess !" << endl;
	
	char *msg = new char[MAXBUF];
	char *buf = new char[MAXBUF];
	int ret;
	struct timeval timev;
	while(1){
//	for(int i = 0; i < 10; i++){
		for (int i = 0; i != SOCKET_NUM; ++i) {
			ret = write(sockfd[i], msg, MAXBUF);
			if(ret < 0){
				perror("write");
				break;
			}
		}

		int resp_nums = 0;
		while(resp_nums < SOCKET_NUM){

			pollfd fds[SOCKET_NUM];
			for (int i = 0; i != SOCKET_NUM; ++i) {
				fds[i].fd = sockfd[i];
				fds[i].events = POLLIN;
			}
			int n = poll(fds, SOCKET_NUM, 1000);
			if (n == -1) {
				perror("poll");
				break;
			}
			for (int i = 0; i != SOCKET_NUM; i++) {
				if (fds[i].revents & POLLIN) {
					ret = read(sockfd[i], buf, MAXBUF);
					if(ret < 0){
						perror("read");
						break;
					}
					resp_nums++;
				}
			}
		}
	}

	delete [] msg;
	delete [] buf;
	for (int i = 0; i != SOCKET_NUM; i++) {
		close(sockfd[i]);
		cout << "close: " << sockfd[i] << endl;
	}
}
/*
void *thread_func(void *ptr){

	int sockfd;
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1){
		perror("socket()");
		return NULL;
	}
	cout << "sockfd: " << sockfd << endl;
	
	struct sockaddr_in dest_addr;
	bzero(&dest_addr, sizeof(dest_addr));
	dest_addr.sin_family = AF_INET;
	dest_addr.sin_port = htons(client_port);
	dest_addr.sin_addr.s_addr = inet_addr(client_ip);

	struct  timeval begin,end;
	gettimeofday(&begin,0);
	
	int flag = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));

	struct timeval connTimeout;
	connTimeout.tv_sec = 0;
	connTimeout.tv_usec = 100000;
	
	if (connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in)) != 0){
		cout << "fd :" << sockfd << endl;
		perror("connect()");
		close(sockfd);
		return NULL;
	}
	
	cout << "connect sucess !" << endl;
	
	char *msg = new char[MAXBUF];
	char *buf = new char[MAXBUF];
	int ret;
	struct timeval timev;
	while(1){
//	for(int i = 0; i < 10; i++){
		ret = write(sockfd, msg, MAXBUF);
		if(ret < 0){
			perror("write");
			break;
		}

		ret = read(sockfd, buf, MAXBUF);
		if(ret < 0){
			perror("read");
		}
	}

	delete [] msg;
	delete [] buf;
	close(sockfd);
	cout << "close: " << sockfd << endl;
}
*/

